import org.apache.commons.lang3.SerializationUtils;
import org.junit.Test;

import java.util.*;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

/**
 *
 * git地址

 https://gitee.com/yujianlong1988/java8andDisruptor.git
 * 收集器
 * @author yujianlong
 * @create 2018-06-16 11:29
 **/
public class OptionalTest1 {

	@Test
	public void initTest1() {//初始化
		Optional.empty();//空的Optional
		Optional.of("A");//
		Optional.ofNullable("A");//
		Optional.ofNullable(null);//允许空值
		//区别
//		System.out.println(Optional.of(null).orElse(""));//直接 NullPointerException
		System.out.println(Optional.ofNullable(null).orElse("ok"));//直接 NullPointerException

	}


	public static String UUID(){
		return UUID.randomUUID().toString().replaceAll("-", "");
	}

	@Test
	public void mapTest1() {//map映射
		List<Map<String, Object>> data = IntStream.rangeClosed(1, 40).boxed().parallel().map(i -> {
			Map<String, Object> map = new HashMap<>();
			map.put("name", UUID());
			map.put("age", i);
			return map;
		}).collect(Collectors.toList());
		//现在要映射第一个数据的name字段和age字段
		Optional<Object> name = Optional.ofNullable(data.get(0)).map(m -> m.get("name"));
		Optional<Object> age = Optional.ofNullable(data.get(0)).map(m -> m.get("age"));
		System.out.println(name.get());
		System.out.println(age.get());
		Optional<String> s = Optional.ofNullable(data.get(0)).map(m -> m.get("name") + "_" + m.get("age"));
		System.out.println(s.get());

		//现在获取所有姓名

		List<Object> nameList = data.parallelStream().map(m1 -> Optional.ofNullable(m1).map(m -> m1.get("name")))
				.map(Optional::get).collect(Collectors.toList());
		System.out.println(nameList);


	}




	public static class Father{//父亲
		private Optional<Son> son;

		public Optional<Son> getSon() {
			return son;
		}

		public void setSon(Optional<Son> son) {
			this.son = son;
		}

	}
	public static class Son{//儿子
		private Optional<Toy> toy;

		public Optional<Toy> getToy() {
			return toy;
		}

		public void setToy(Optional<Toy> toy) {
			this.toy = toy;
		}

	}
	public static class Toy{//玩具
		private String name;

		public String getName() {
			return name;
		}

		public void setName(String name) {
			this.name = name;
		}

		@Override
		public String toString() {
			return "Toy{" +
					"name='" + name + '\'' +
					'}';
		}
	}

	@Test
	public void flatMapTest1() {//flatmap映射
		//父亲儿子玩具 现在好多都单身，但是都有有儿子的可能，假设有了儿子，他也有有玩具的可能
		//optional就可做这个事，不至于获取你儿子的玩具中间报了空指针

		Father father=null;
		Optional<Optional<Son>> op_son = Optional.ofNullable(father)
				.map(Father::getSon);//这里获取的是Optional<Optional<Son>> 类型的

		//那么我们要获取son就要两边get
//		Son son = op_son.get().get();
//		System.out.println(son);
		//为甚会报错呢
		//op_son.get()返回的是一个Optional<Son> 他就相当于一个Optional.of(null) 它再get就出问题
		System.out.println(op_son.orElse(Optional.empty()).orElse(null));

		//那么我们如何直接获取玩具不报错
		String toyname = Optional.ofNullable(father)
				.flatMap(Father::getSon)
				.flatMap(Son::getToy)//只要map返回Optional<Optional就还是要使用flatmap 什么是否只有一层只要map返回Optional<才可以使用map
				.map(Toy::getName)
				.orElse("nohave");
		System.out.println(toyname);//这样不会报错

	}

	@Test
	public void otherTest1() {//其他方法

		//orelseGet

		Callable<Integer> call1 = () -> {
			TimeUnit.SECONDS.sleep(1);
			System.out.println("1");
			return 1;
		};
		Callable<Integer> call2 = () -> {
			TimeUnit.SECONDS.sleep(1);
			System.out.println("2");
			return 2;
		};
		Optional<Callable> op_call = Optional.ofNullable(call1);
		Callable callable = op_call.orElseGet(() -> call2);
		try {
			callable.call();
		} catch (Exception e) {
			e.printStackTrace();
		}

		//orelsethrow
//		op_call.orElseThrow(()->new RuntimeException("asasa"));

		boolean present = op_call.isPresent();

		System.out.println(present);
		op_call.ifPresent(callable1 -> {

			try {
				callable1.call();
			} catch (Exception e) {
				e.printStackTrace();
			}
		});
	}

	@Test
	public void filterTest1() {
		Optional.ofNullable("1").filter(s->Objects.equals(s,"2")).ifPresent(System.out::println);
	}


}
